package com.zhuozhou.jdyc.util.update;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.view.View;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import com.zhuozhou.jdyc.api.ConstantsHelper;
import com.zhuozhou.jdyc.util.log.ToastUtils;
import com.zhuozhou.jdyc.util.update.callback.DownloadCallback;
import com.zhuozhou.jdyc.util.update.server.DownloadApkReceiver;
import com.zhuozhou.jdyc.util.update.util.UpdateNotificationApkUtil;
import com.zhuozhou.jdyc.wight.dialog.UpdateMessageDialog;

import java.io.File;

import io.reactivex.disposables.Disposable;


/**
 * Created by 方舟 on 2016/11/23.
 * describe：软件版本更新
 */
public class UpdateManger implements UpdateMessageDialog.OnUpdateListener {
    // 应用程序Context
    private static Activity mContext;
    // 提示消息
    private String updateMsg = "有最新的软件包，请下载！";
    // 下载安装包的网络路径
    private String apkUrl;
    // 进度条与通知UI刷新的handler和msg常量
    private static UpdateManger updateManger;
    private DownloadApkReceiver downloadApkReceiver;

    private UpdateManger() {

    }

    public static UpdateManger getInstance() {
        if (updateManger == null) {
            updateManger = new UpdateManger();
        }
        return updateManger;
    }

    /**
     * 显示更新程序对话框，供主程序调用
     * @param mContext 视图
     * @param apkUrl apk地址
     * @param updateMsg  更新提示信息
     * @param mCurrentVersionName 当前版本名称
     */
    public void checkUpdateInfo(Activity mContext, String apkUrl, String updateMsg,
                                String mCurrentVersionName) {
        this.apkUrl = apkUrl;
        UpdateManger.mContext = mContext;
        if (updateMsg != null && !"".equals(updateMsg)) {
            this.updateMsg = updateMsg;
        }
        new UpdateMessageDialog(mContext)
                .setOnUpdateListener(this)
                .builder(mCurrentVersionName, updateMsg)
                .show();
    }

    public static void installApk(Context mContext, File apkFile) {
        if (!apkFile.exists()) {
            return;
        }
        Intent i = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK |
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
            Uri apkFileUri = FileProvider.getUriForFile(mContext.getApplicationContext(),
                    mContext.getPackageName() + ".FileProvider", apkFile);
            i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
            UpdateNotificationApkUtil notificationUtils = UpdateNotificationApkUtil.getInstance();
            notificationUtils.clearAllNotification();
            notificationUtils.sendNotificationFullScreen("新版本已下载完成", "点击安装", apkFile);
            mContext.startActivity(i);
        } else {
            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
                    "application/vnd.android.package-archive");
            mContext.startActivity(i);
        }
    }

    @Override
    public void onUpdate(View v) {
        if (ConstantsHelper.isDownLoadApk) {
            ToastUtils.showShort(mContext, "已存在下载任务，请勿重复下载");
            return;
        }

        if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            ActivityCompat.requestPermissions(mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    0x01);
        } else {
            if (downloadApkReceiver == null) {
                downloadApkReceiver = new DownloadApkReceiver();
            }
            mContext.registerReceiver(downloadApkReceiver, getIntentFilter());
            Intent intent = new Intent();
            intent.putExtra(DownloadApkReceiver.NOTIFY_ID, ConstantsHelper.DOWNLOAD_CHANNEL_ID.hashCode());
            RxNet.download(apkUrl, RxNet.PATH + ConstantsHelper.APK_NAME, new DownloadCallback() {
                @Override
                public void onStart(Disposable d) {
                    if (mContext != null) {
                        intent.setAction(RxNet.ACTION_START);
                        mContext.sendBroadcast(intent);
                    }
                }

                @Override
                public void onProgress(long totalByte, long currentByte, int progress) {
                    intent.setAction(RxNet.ACTION_UPDATE);
                    intent.putExtra(DownloadApkReceiver.PROGRESS_RATE, progress);
                    if (mContext != null) {
                        mContext.sendBroadcast(intent);
                    }
                }

                @Override
                public void onFinish(File file) {
                    intent.setAction(RxNet.ACTION_FINISHED);
                    intent.putExtra(DownloadApkReceiver.IS_DOWNLOAD_APK,true);
                    intent.putExtra(DownloadApkReceiver.APK_FILE_PATH, file.getAbsolutePath());
                    mContext.sendBroadcast(intent);
                }

                @Override
                public void onError(String msg) {
                    intent.setAction(RxNet.ACTION_ERROR);
                    if (mContext != null) {
                        mContext.sendBroadcast(intent);
                    }
                }
            });
        }
    }

    private IntentFilter getIntentFilter() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(RxNet.ACTION_START);
        intentFilter.addAction(RxNet.ACTION_UPDATE);
        intentFilter.addAction(RxNet.ACTION_FINISHED);
        intentFilter.addAction(RxNet.ACTION_CANCEL);
        intentFilter.addAction(RxNet.ACTION_ERROR);
        intentFilter.addAction(RxNet.ACTION_REDIRECT_ERROR);
        return intentFilter;
    }
}
